package net.cmkj.mine.bean;

import com.jfinal.aop.Before;
import com.jfinal.kit.StrKit;
import com.jfinal.plugin.activerecord.Db;
import com.jfinal.plugin.activerecord.Page;
import com.jfinal.plugin.activerecord.Record;
import com.jfinal.plugin.activerecord.tx.Tx;
import com.jfinal.plugin.ehcache.CacheKit;
import net.cmkj.mine.bean.base.BaseSysRes;
import net.cmkj.mine.common.cache.CacheClearUtils;
import net.cmkj.mine.common.cache.CacheName;
import net.cmkj.mine.common.model.Condition;
import net.cmkj.mine.common.model.InvokeResult;
import net.cmkj.mine.common.model.Operators;
import net.cmkj.mine.common.model.ZtreeView;
import net.cmkj.mine.util.BeanUtils;
import net.cmkj.mine.util.CommonUtils;
import org.apache.log4j.LogManager;
import org.apache.log4j.Logger;

import java.util.*;

/**
 * Generated by JFinal.
 */
@SuppressWarnings("serial")
public class SysRes extends BaseSysRes<SysRes> {

	public static final SysRes dao = new SysRes().dao();
	
	private static Logger log = LogManager.getLogger(SysRes.class);
	
	public Map<String,Object> getTreeGridView(){
		log.info("获取资源列表");
		Map<String,Object> rows=new HashMap<String,Object>();
		List<Map<String,Object>> list=new ArrayList<Map<String,Object>>();
		LinkedHashMap<String, String> orderby=new LinkedHashMap<String,String>();
		orderby.put("seq", "asc");
		List<SysRes> allTopMenuList=this.getList(1,10000,null,orderby);
		for(SysRes item : allTopMenuList){
			Map<String,Object> mapItem=new HashMap<String,Object>();
			mapItem.put("id", item.getInt("id"));
			mapItem.put("name", item.getStr("name"));
			mapItem.put("pId", item.getInt("pid"));
			mapItem.put("iconcls", item.getStr("iconcls"));
			mapItem.put("des", item.getStr("des"));
			mapItem.put("url", item.getStr("url"));
			mapItem.put("seq", item.getInt("seq"));
			mapItem.put("level", item.getInt("level"));
			mapItem.put("type", item.getInt("type"));
			mapItem.put("status", item.getInt("status"));
			list.add(mapItem);
		}
		rows.put("msg", "");
		rows.put("code", 0);
		rows.put("data", list);
		rows.put("count", list.size());
		return rows;
	}
	
	/**
	 * 获取用户的所有资源
	 */
	public Set<String> getSysUserAllResUrl(int uid){
		Set<String> sets=CacheKit.get(CacheName.userMenuCache, "getSysUserAllResUrl_"+uid);
		if(sets==null){
			List<SysRes> list = getSysResList(uid,null);
			sets = new HashSet<String>();
			for(SysRes item : list){
				sets.add(item.getStr("url"));
			}
			List<Record> buttons = Db.find("select r.url from res_user t left join sys_res r on t.res_id = r.id where t.user_id = ? and r.type = 2", uid);
			for (Record record : buttons) {
				sets.add(record.getStr("url"));
			}
			CacheKit.put(CacheName.userMenuCache, "getSysUserAllResUrl_"+uid, sets);
		}
		return sets;
	}
	
	/**
	 * 获取系统用户资源
	 */
	public String getSysUserMenuView(int uid) {
		String menuhtml=CacheKit.get(CacheName.userMenuCache, "getSysUserMenuView_"+uid);
		if(StrKit.notBlank(menuhtml)){
			return menuhtml;
		}
		StringBuffer sbBuilder = new StringBuffer();
		getSysUserMenuView(sbBuilder, uid);
		return sbBuilder.toString();
	}

	public void getSysUserMenuView(StringBuffer sbBuilder, int uid) {
		List<SysRes> allMenuList = getSysResList(uid,1);
        List<SysRes> userResList = SysUser.dao.getUserResList(uid, 1);
        Set<Integer> set = new HashSet<Integer>();
        for (SysRes menu : allMenuList) {
            set.add(menu.getId());
        }
        for (SysRes userRes : userResList) {
            if (set.add(userRes.getId())) {
                allMenuList.add(userRes);
            }
        }
        Map<Integer,List<SysRes>> subMapList = new HashMap<Integer,List<SysRes>>();
        for(SysRes menu : allMenuList){
            if(menu.getInt("pid") != null){
                List<SysRes> list = subMapList.get(menu.getInt("pid"));
                if(list == null){
                    list = new ArrayList<SysRes>();
                }
                list.add(menu);
                subMapList.put(menu.getInt("pid"), list);
            }
        }
		int i = 0;
		for(SysRes menu : allMenuList){
			if(menu.getInt("pid") == null){
				if("/".equals(menu.getStr("url"))) {
					continue;
				}
				sbBuilder.append("<li class='layui-nav-item ");
				if(i == 0){
					sbBuilder.append("layui-nav-itemed");
				}
				sbBuilder.append(" '>");
				i++;
				List<SysRes> childs = subMapList.get(menu.getInt("id"));
				if (childs != null && childs.size()>0) {//二级
					sbBuilder.append("<a href='javascript:;' lay-tips='"+menu.getStr("name")+"' lay-direction='2'><i class='layui-icon "+menu.getStr("iconcls")+"'></i>&nbsp;&nbsp;<cite>"+menu.getStr("name")+"</cite></a>");
					sbBuilder.append("<dl class='layui-nav-child'>");
					for(SysRes subMenu : childs){
						sbBuilder.append("<dd><a href='javascript:;' title='"+subMenu.getStr("name")+"' lay-href='"+subMenu.getStr("url")+"' data-url='"+subMenu.getStr("url")+"' data-id='"+subMenu.getStr("id")+"' data-text='"+subMenu.getStr("name")+"' data-icon='"+subMenu.getStr("iconcls")+"'>&nbsp;&nbsp;&nbsp;&nbsp;<i class='layui-icon "+subMenu.getStr("iconcls")+"'></i>&nbsp;&nbsp;"+subMenu.getStr("name")+"</a></dd>");
					}
					sbBuilder.append("</dl>");
				} else {
					sbBuilder.append("<a href='javascript:;'><i class='layui-icon "+menu.getStr("iconcls")+"'></i>"+menu.getStr("name")+"</a>");
				}
				sbBuilder.append("</li>");
			}
		}
		CacheKit.put(CacheName.userMenuCache, "getSysUserMenuView_"+uid,sbBuilder.toString());
	}
	
	/**
	 * 
	 * @author zzcmkj	
	 * @param uid 用户ID
	 * @param type 菜单|功能
	 * @return
	 */
	public List<SysRes> getSysResList(int uid,Integer type){
		List<SysRes> resList = CacheKit.get(CacheName.userMenuCache, "getSysResList_"+uid+"_"+type);
		if(resList == null||resList.size() == 0){
            List<SysRole> sysRoleIds = SysRole.dao.getSysRoleIdList(uid);
            if(sysRoleIds.size() == 0){
                return null;
            }else{
                getSysResList(resList,uid,type);
                resList = CacheKit.get(CacheName.userMenuCache, "getSysResList_"+uid+"_"+type);
            }
		}
		return resList;
	}

	public void getSysResList(List<SysRes> resList,int uid,Integer type){
        List<SysRole> sysRoleIds = SysRole.dao.getSysRoleIdList(uid);
        StringBuffer roleIds=new StringBuffer();
        boolean isAdmin=false;
        for(SysRole sysRole : sysRoleIds){
            if(sysRole.getId().equals(1))isAdmin=true;
            roleIds.append(sysRole.getInt("id")).append(",");
        }
        roleIds.deleteCharAt(roleIds.length()-1);
        if(type!=null){
            if(!isAdmin){
                resList= this.find("select * from sys_res where id in(select res_id from sys_role_res where role_id in("+roleIds.toString()+")) and type="+type+" and status=1 order by seq asc");
            }else{
                resList= this.find("select * from sys_res where type="+type+" and status=1 order by seq asc");
            }
        }else{
            if(!isAdmin){
                resList= this.find("select * from sys_res where id in(select res_id from sys_role_res where role_id in("+roleIds.toString()+")) and status=1 order by seq asc");
            }else{
                resList= this.find("select * from sys_res where status=1 order by seq asc");
            }
        }
        CacheKit.put(CacheName.userMenuCache, "getSysResList_"+uid+"_"+type, resList);
	}

	public List<SysRes> getSysResMenuByPid(List<SysRole> sysRoleIds,int pid){
		if(sysRoleIds.size()==0)return null;
		StringBuffer roleIds=new StringBuffer();
		for(SysRole sysRole : sysRoleIds){
			roleIds.append(sysRole.getInt("id")).append(",");
		}
		roleIds.deleteCharAt(roleIds.length()-1);
		return this.paginate(1, 10000, "select *", "from sys_res where id in(select res_id from sys_role_res where role_id in("+roleIds.toString()+")) and pid =? and type=1 order by seq asc",pid).getList();
	}
	
	public SysRes getByUrl(String url){
		return this.findFirst("select * from sys_res where url=?", url);
	}
	
	/**
	 * 获取上级资源
	 * @return
	 */
	public List<ZtreeView> getZtreeViewList() {
		List<ZtreeView> ztreeViews = new ArrayList<ZtreeView>();
		List<SysRes> sysResType = this.getTopList();
		if(sysResType.size()>0){
			int i=1;
			for(SysRes cate:sysResType){
				ztreeViews.add(new ZtreeView(cate.getInt("id"), cate.getInt("pid"), cate.getStr("name"), i==1?true:false));
			}
			i++;
		}
		return ztreeViews;
	}
	
	public List<SysRes> getTopList() {
		// TODO Auto-generated method stub
		LinkedHashMap<String, String> orderby=new LinkedHashMap<String,String>();
		orderby.put("seq", "asc");
		Set<Condition> conditions=new HashSet<Condition>();
		conditions.add(new Condition("type",Operators.EQ,1));
		List<SysRes> allTopMenuList=this.getList(1,10000,conditions,orderby); 
		return allTopMenuList;
	}
	
	/**
	 * 获取列表
	 * @param pageNumber
	 * @param pageSize
	 * @param name
	 * @param status
	 * @return
	 */
	public Page<SysRes> paginate(int pageNumber, int pageSize, String name, Integer status, String orderbyStr) throws Exception {
		log.info("获取列表");
		List<Object> params = new ArrayList<Object>();
		StringBuffer sqlExceptSelect=new StringBuffer("from sys_res t where 1=1");
		if(CommonUtils.isNotEmpty(name)){
			sqlExceptSelect.append(" and t.name like ?");
			params.add(name);
		}
		if(status != null){
			sqlExceptSelect.append(" and t.status=?");
			params.add(status);
		}
		sqlExceptSelect.append(" "+orderbyStr);
		return dao.paginate(pageNumber, pageSize, "SELECT t.* ", sqlExceptSelect.toString(), CommonUtils.listToArr(params));
	}
	
	/**
	 * 获取对象
	 * @param id
	 * @return
	 */
	public SysRes findById(long id) throws Exception {
		log.info("获取对象");
		return dao.findFirst("select * from sys_res where id=?", id);
	}

	public List<CmkjTree> getChildren(Integer pid) throws Exception {
		log.info("获取子节点树");
		List<CmkjTree> trees = new ArrayList<>();
		List<SysRes> children = dao.find("select * from sys_res where pid = ?", pid);
		for (SysRes res : children) {
			CmkjTree tree=new CmkjTree();
			tree.setId(CommonUtils.converString(res.getId()));
			tree.setTitle(res.getName());
			trees.add(tree);
		}
		return trees;
	}
	
	public InvokeResult save(Integer id,String name,String seq,String url,String iconcls,String des,Integer type,Integer pId) throws Exception {
		if(id!=null){
			SysRes sysRes=dao.findById(id);
			sysRes.set("name", name).set("seq", seq).set("url", url).set("iconcls", iconcls).set("des", des).
			set("type", type).set("pid", pId).update();
		}else{
			SysRes res=new SysRes();
			res.set("name", name).set("seq", seq).set("url", url).set("iconcls", iconcls).set("des", des).
			set("type", type).set("pid", pId).set("createdate", new Date()).save();
			Integer resId=res.getId();//获取刚保存Id
			//保存角色资源权限res_id role_id （角色默认为管理员）
			Record roleRes=new Record().set("res_id", resId).set("role_id", 1);
			Db.save("sys_role_res",roleRes);
		}
		CacheClearUtils.clearUserMenuCache();
		return InvokeResult.success();
	}
	
	/**
	 * 对象保存
	 * @param model
	 * @return
	 */
	@Before(Tx.class)
	public InvokeResult save(SysRes model) throws Exception {
		log.info("对象保存");
	    boolean flag = false;
		if (null == model.getId()) {
			flag = model.save();
		} else {
			SysRes src = model.findById(model.getId());
			log.info(BeanUtils.compare(src, model));
			flag = model.update();
		}
		if (flag) {
			return InvokeResult.success();
		} else {
			return InvokeResult.failure("对象保存失败！");
		}
	}
	
	/**
	 * 对象删除
	 * @param ids
	 * @return
	 */
	@Before(Tx.class)
	public InvokeResult deleteByIds(String ids) throws Exception{
		log.info("对象删除");
    	String idarr[] = ids.split(",");
    	for (String id : idarr) {
    		if (!dao.findById(id).delete()) {
    			log.error("批量删除失败！");
    			throw new RuntimeException(id+"批量删除失败");
    		}
    	}
    	return InvokeResult.success();
	}

    /**
     * 对象删除
     * @param pid
     * @return
     * @throws Exception
     */
	@Before(Tx.class)
	public InvokeResult deleteByPid(Integer pid) throws Exception{
		log.info("对象删除");
        Db.update("delete from sys_res where pid = ?",pid);
    	return InvokeResult.success();
	}

	/**
	 * 修改资源启用状态
	 * @param id
	 * @param visible
	 * @return
	 */
	public InvokeResult setVisible(Integer id, Integer visible) throws Exception {
		SysRes sysRes=this.findById(id);
		sysRes.set("status", visible).update();
		CacheClearUtils.clearUserMenuCache();
		return InvokeResult.success();
	}
	
	/**
	 * 修改对象状态
	 * @param ids
	 * @return
	 */
	@Before(Tx.class)
	public InvokeResult setStatus(String ids, Integer status) throws Exception{
		log.info("对象状态变更");
		String idarr[] = ids.split(",");
    	for(String id : idarr){
    		if (!dao.findById(id).set("status", status).update()) {
    			log.error("对象批量状态变更失败！");
    			throw new RuntimeException(id+"状态批量变更失败！");
    		}
		}
		return InvokeResult.success();
	}

	public List<Record> getData() throws Exception{
		return Db.find("SELECT * FROM `sys_res` where ISNULL(pid) and `status` =1");
	}
}
